// TilesetView.cpp : implementation file
//

#include "stdafx.h"
#include "MapEditor.h"
#include "TilesetView.h"
#include "MemDC.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTilesetView

IMPLEMENT_DYNCREATE(CTilesetView, CScrollView)

CTilesetView::CTilesetView()
{
}

CTilesetView::~CTilesetView()
{
}


BEGIN_MESSAGE_MAP(CTilesetView, CScrollView)
	//{{AFX_MSG_MAP(CTilesetView)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDOWN()
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTilesetView drawing

void CTilesetView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	VERIFY(m_brBkgnd.CreateSolidBrush(RGB(128, 128, 128)));
	VERIFY(m_pnLine.CreatePen(PS_SOLID, 1, RGB(191, 191, 191)));

	Resize();
}

void CTilesetView::Resize()
{
	CSize sizeTotal;
	sizeTotal.cx = sizeTotal.cy = 100;

	CEditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CTilesetKit* pKit = pDoc->m_pTilesetKit;
	if(pKit)
	{
		sizeTotal.cx += pKit->m_nWidth;
		sizeTotal.cy += pKit->m_nHeight;
	}

	SetScrollSizes(MM_TEXT, sizeTotal);
}

/////////////////////////////////////////////////////////////////////////////
// CTilesetView diagnostics

#ifdef _DEBUG
void CTilesetView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CTilesetView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CEditorDoc* CTilesetView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CEditorDoc)));
	return (CEditorDoc*)m_pDocument;
}
#endif //_DEBUG


/////////////////////////////////////////////////////////////////////////////
// CTilesetView message handlers

BOOL CTilesetView::OnEraseBkgnd(CDC* pDC) 
{
	return 1;
}

void CTilesetView::OnDraw(CDC* pDC)
{
	POINT ptOrg;
	ptOrg.x = 0;
	ptOrg.y = 0;

	CSize tSize = GetTotalSize();

	RECT rect;
	GetClientRect(&rect);
	rect.left = 0;
	rect.top = 0;
	if(rect.right < tSize.cx)
		rect.right = tSize.cx;
	if(rect.bottom < tSize.cy)
		rect.bottom = tSize.cy;

	CEditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CMemDC* pMemDC = new CMemDC(pDC, rect);
	pMemDC->EraseBkgnd(m_brBkgnd);

	CTilesetKit* pKit = pDoc->m_pTilesetKit;
	if(pKit && pKit->m_pTiles)
	{
		int cx = pKit->m_nWidth / pKit->m_nTx;
		int cy = pKit->m_nHeight / pKit->m_nTy;

		int x = 0;
		int y = 0;

		for(int i=0; i<pKit->m_nTotal; i++)
		{
			TILE& rTile = pKit->m_pTiles[i];

			rTile.xImage.Draw(pMemDC->GetSafeHdc(), x, y);

			x += pKit->m_nTx;
			if(x >= pKit->m_nWidth)
			{
				x = 0;
				y += pKit->m_nTy;
			}
		}

		if(pKit->m_nSelect != -1)
		{
			CPen pen(0, 1, RGB(255, 0, 0));
			CPen* pOld = (CPen*)pMemDC->SelectObject(&pen);

			int x1 = (pKit->m_nSelect % pKit->m_nCol) * pKit->m_nTx;
			int y1 = (pKit->m_nSelect / pKit->m_nCol) * pKit->m_nTy;
			int x2 = x1 + (pKit->m_nTx * pKit->m_nCX);
			int y2 = y1 + (pKit->m_nTy * pKit->m_nCY);

			pMemDC->MoveTo(x1, y1);
			pMemDC->LineTo(x2, y1);
			pMemDC->LineTo(x2, y2);
			pMemDC->LineTo(x1, y2);
			pMemDC->LineTo(x1, y1);

			pMemDC->SelectObject(pOld);
		}
	}

	delete pMemDC;
}

int CTilesetView::HitTest(const CPoint& pt)
{
	CEditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CTilesetKit* pKit = pDoc->m_pTilesetKit;
	if(pKit && pKit->m_pTiles)
	{
		int cx = pKit->m_nWidth / pKit->m_nTx;
		int cy = pKit->m_nHeight / pKit->m_nTy;

		int x = pt.x / pKit->m_nTx;
		int y = pt.y / pKit->m_nTy;
		
		x = x > cx ? cx : x;
		y = y > cy ? cy : y;

		return (y * cx) + x;
	}
	return -1;
}

void CTilesetView::OnMouseMove(UINT nFlags, CPoint point) 
{
	CEditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CTilesetKit* pKit = pDoc->m_pTilesetKit;
	if(pKit && pKit->m_pTiles)
	{
		if(nFlags & MK_LBUTTON)
		{
			CPoint pts = GetScrollPosition();
			CPoint pt = point - pts;

			if(pKit->m_nSelect == -1)
			{
				pKit->m_nSelect = HitTest(pt);
				pKit->m_nCX = 1;
				pKit->m_nCY = 1;
			}
			else
			{
				if(pt.x > pKit->m_nWidth)
					pt.x = pKit->m_nWidth;
				if(pt.y > pKit->m_nHeight)
					pt.y = pKit->m_nHeight;

				int cx = pKit->m_nWidth / pKit->m_nTx;
				int cy = pKit->m_nHeight / pKit->m_nTy;

				int x = pt.x / pKit->m_nTx;
				int y = pt.y / pKit->m_nTy;
				
				x = x > cx ? cx : x;
				y = y > cy ? cy : y;


				int x1 = pKit->m_nSelect % pKit->m_nCol;
				int y1 = pKit->m_nSelect / pKit->m_nCol;
				
				int x2 = x;
				int y2 = y;

				if(x1 > x2)
					swap(x1, x2);
				if(y1 > y2)
					swap(y1, y2);
				
				cx = x2 - x1;
				cy = y2 - y1;

				pKit->m_nCX = cx > 1 ? cx : 1;
				pKit->m_nCY = cy > 1 ? cy : 1;

				pKit->m_nSelect = (y1 * pKit->m_nCol) + x1;
				
				if(pKit->m_nSelect != -1)
				{
					CRect rect;
					rect.left = (pKit->m_nSelect % pKit->m_nCol) * pKit->m_nTx;
					rect.top = (pKit->m_nSelect / pKit->m_nCol) * pKit->m_nTy;
					rect.right = rect.left + (pKit->m_nTx * pKit->m_nCX) + 1;
					rect.bottom = rect.top + (pKit->m_nTy * pKit->m_nCY) + 1;
					
					Invalidate();
				}
				
			}
		}
	}
	CScrollView::OnMouseMove(nFlags, point);
}

void CTilesetView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	CScrollView::OnLButtonUp(nFlags, point);
}

void CTilesetView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CEditorDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CTilesetKit* pKit = pDoc->m_pTilesetKit;
	if(pKit)
	{
		if(pKit->m_nSelect != -1)
		{
			pKit->m_nSelect = -1;
			Invalidate();
		}
	}
	
	CScrollView::OnLButtonDown(nFlags, point);
}
